package com.autumn.dubbo.spring.boot.context.event;

import java.lang.reflect.Field;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.Banner;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.logging.LoggingApplicationListener;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;

import com.alibaba.dubbo.common.Version;
import com.alibaba.dubbo.qos.server.DubboLogo;
import com.autumn.dubbo.spring.boot.bean.DubboSpringBootStarterConstants;

/**
 * Dubbo banner
 * 
 * @author 老码农
 *
 *         2018-07-03 14:10:47
 */
@Order(LoggingApplicationListener.DEFAULT_ORDER + 1)
public class DubboBannerApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

	private static final Log logger = LogFactory.getLog(DubboBannerApplicationListener.class);

	private Banner.Mode getBannerMode(SpringApplication application) {
		try {
			Field field = SpringApplication.class.getDeclaredField("bannerMode");
			try {
				field.setAccessible(true);
				Banner.Mode mode = (Mode) field.get(application);
				return mode;
			} catch (IllegalArgumentException | IllegalAccessException e) {
				return Banner.Mode.OFF;
			}
		} catch (NoSuchFieldException | SecurityException e) {
			return Banner.Mode.OFF;
		}
	}

	@Override
	public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
		Banner.Mode mode = this.getBannerMode(event.getSpringApplication());
		if (mode == Banner.Mode.OFF) {
			return;
		}
		String bannerText = this.buildBannerText();
		if (mode == Mode.CONSOLE) {
			System.out.print(bannerText);
		} else if (mode == Mode.LOG) {
			logger.info(bannerText);
		}
	}

	private String buildBannerText() {
		StringBuilder bannerTextBuilder = new StringBuilder();
		bannerTextBuilder.append(DubboSpringBootStarterConstants.LINE_SEPARATOR).append(DubboLogo.dubbo)
				.append(":: Dubbo ::        (v").append(Version.getVersion()).append(")")
				.append(DubboSpringBootStarterConstants.LINE_SEPARATOR);
		return bannerTextBuilder.toString();
	}
}
